package com.ufo.threads;

public class ThreadState {
    public static void main(String[] args){
        for(Thread.State s:Thread.State.values()){//Thread.State is enum
            System.out.println("all states:"+s);
        }
        try {
            example2();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void example1(){
        Runnable r=new Runnable() {
            @Override
            public void run() {
                int i=0;
                while(i<5){
                    i++;
                    try {
                        System.out.println("to sleep");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        Thread th=new Thread(r);
        System.out.println("now in states:"+th.getState());
        Thread watcher=new Thread(()->{
            int i=0;
            while(i<8){
                i++;
                try {
                    if(i==3){
                        System.out.println("interrupt !!:"+th.getState());
                        th.interrupt();
                    }
                    System.out.println("from watcher now in states:"+th.getState());
                    Thread.sleep(800);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        th.start();
        watcher.start();
        try {
            System.out.println("now in states:"+th.getState());
            th.join();
            System.out.println("now in states:"+th.getState());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //剧本：th1 sleep 1000        ->      th1 wait         ->                  end!
    //     th2 sleep 200 -> try to get lock -> th2 get lock ->th2 notify all  end!
    public static void example2() throws InterruptedException {
        Thread t1=new Thread(()->{
            synchronized (ThreadState.class){
                try {
                    System.out.println("th1 sleep 1s");
                    Thread.sleep(1000);
                    System.out.println("th1 wait");
                    ThreadState.class.wait();//让锁wait，会释放锁，进入WAITING

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        });
        Thread t2=new Thread(()->{
            try {
                System.out.println("th2 sleep 200ms");
                Thread.sleep(200);// 线程1必然拿到锁
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (ThreadState.class){ //t2正在竞争锁，此时BLOCKED
                try {
                    System.out.println("th2 got and sleep 1s");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("th2 notify all");
                ThreadState.class.notifyAll();
            }
        });
        t1.start();
        t2.start();
        Thread.sleep(300);
        System.out.println("300ms now th1 "+t1.getState()+" th2 "+t2.getState());
        Thread.sleep(800);
        System.out.println("1100ms now th1 "+t1.getState()+" th2 "+t2.getState());
        Thread.sleep(500);
        System.out.println("1600ms now th1 "+t1.getState()+" th2 "+t2.getState());
        t1.join();
        t2.join();
    }
}
